﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.Serialization;
using NUnit.Framework;
using Sripirom.Pattern.UnitTest.Core.UnitTest;

namespace Sripirom.Pattern.UnitTest.Simple.Test
{
    [TestFixture]
    public class SimpleClassTest
    {
        private ISimpleClass _clazz;
        private const string _categoryName = "Sripirom.Pattern.UnitTest.Simple.Test.SimpleClassTest";
        private const string _classId = "Cls1";
        public SimpleClassTest()
        {
            _clazz = new SimpleClass();
        }

        [Test, CustomTestCaseSource(_categoryName, _classId, "F1")]
        public void Plus(Int32 obj1, Int32 obj2, Int32 response, params string[] ignore)
        {
            Assert.IsTrue(response.Compare<Int32>(_clazz.Plus(obj1, obj2), ignore));
        }

        [Test, CustomTestCaseSource(_categoryName, _classId, "F2")]
        public void Invoke(SimpleRequest request, SimpleResponse response, params string[] ignore)
        {
            Assert.IsTrue(response.Compare<SimpleResponse>(_clazz.Invoke(request), ignore));
        }



        [Test]
        public void SerialObjectRequest()
        {

            String xml = SerializeToString(new SimpleRequest() { Id = 1, Data = new DataRequest() { Code = 1, CodeName = "CodeName1" }, Name = "SimpleRequest" });

            xml = xml.Replace("<?xml version=\"1.0\"?>", "").Replace(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"", "");

            // string encodedXml = System.Security.SecurityElement.Escape(xml);

            string encodedXml = HttpUtility.HtmlEncode(xml);


            string decodeXml = HttpUtility.HtmlDecode(encodedXml);


            SimpleRequest obj = Deserialize<SimpleRequest>(decodeXml);

            Assert.IsNotNull(obj);
        }
        [Test]
        public void SerialObjectResponse()
        {

            String xml = SerializeToString(new SimpleResponse() { Id = 1, Data = new DataResponse() { Code = 1, CodeName = "CodeName1" }, Name = "SimpleRequest" });

            xml = xml.Replace("<?xml version=\"1.0\"?>", "").Replace(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"", "");

            // string encodedXml = System.Security.SecurityElement.Escape(xml);

            string encodedXml = HttpUtility.HtmlEncode(xml);


            string decodeXml = HttpUtility.HtmlDecode(encodedXml);


            SimpleResponse obj = Deserialize<SimpleResponse>(decodeXml);

            Assert.IsNotNull(obj);
        }
        public T Deserialize<T>(string xmlText)
        {
            try
            {
                var stringReader = new System.IO.StringReader(xmlText);
                var serializer = new XmlSerializer(typeof(T));
                return (T)serializer.Deserialize(stringReader);
            }
            catch
            {
                throw;
            }
        }
        public string SerializeToString(Object YourClassObject)
        {
            try
            {
                // Represents an XML document, Initializes a new instance of the XmlDocument class.
                XmlDocument xmlDoc = new XmlDocument();

                XmlSerializer xmlSerializer = new XmlSerializer(YourClassObject.GetType());

                // Creates a stream whose backing store is memory. Initializes a new instance of the MemoryStream class with an expandable capacity initialized to zero.
                using (MemoryStream xmlStream = new MemoryStream())
                {
                    xmlSerializer.Serialize(xmlStream, YourClassObject);
                    xmlStream.Position = 0;

                    //Loads the XML document from the specified string.
                    xmlDoc.Load(xmlStream);

                    // Pretty XML
                    //System.Xml.Linq.XDocument doc = System.Xml.Linq.XDocument.Parse(xmlDoc.InnerXml);
                    return xmlDoc.InnerXml;
                    //return xmlDoc.InnerXml
                }
            }
            catch (InvalidOperationException)
            {
                //throw new MessageException(Errors.INVALID_REQUEST_MESSAGE);
            }
            catch (Exception)
            {
                throw;
            }
            return "";
        }


    }


    public static class CompareHelper
    {
        private static string ToStringNullSafe(this object obj)
        {
            return obj != null ? obj.ToString() : String.Empty;
        }
        public static bool Compare<T>(this T a, T b, params string[] ignore)  //where T : class
        {
            Boolean result = true;
            if (a.GetType() == b.GetType())
            {
                int count = a.GetType().GetProperties().Count();
                string aa, bb;
                for (int i = 0; i < count; i++)
                {
                    object objA = a.GetType().GetProperties()[i].GetValue(a, null);
                    object objB = b.GetType().GetProperties()[i].GetValue(b, null);
                    if (Type.GetTypeCode(objA.GetType()) == TypeCode.Object)
                        result = Compare(objA, objB, ignore);

                    aa = objA.ToStringNullSafe();
                    bb = objB.ToStringNullSafe();
                    if (aa != bb && ignore.Where(x => x == a.GetType().GetProperties()[i].Name).Count() == 0)
                    {
                        result = false;
                        break;
                    }
                }
            }
            else
                result = false;

            return result;
        }
    }
}
